import webapp2
import datetime

# from models import Entry
from google.appengine.ext import db
from google.appengine.ext.db import polymodel

# Class Account: Name, email, key
# PolyModel is a superclass
# Short - ac
class Account(polymodel.PolyModel):
	# All models have a key assigned when they are put()
	# You can retrieve this key using Model.key()
	# "We're going to have to have exams every class" -ALK 2/6/12
	email = db.EmailProperty()
	name = db.StringProperty()

# Subclass Admin: password, calendar key
# Short - ad
class Admin(Account):
	password = db.StringProperty()
	calKey = db.ReferenceProperty()

# Subclass User 
# Short - usr
class User(Account):
	pass

# Class Shift: timeframe (list of blocks), assignment (NULL until closed), up 
# for grabs, sub, list of available users' keys, key
# Short - sh
class Shift(db.Model):
	# Time is more complicated. So day 1 = Sunday
	day = db.IntegerProperty()
	# I used floats so we can use 0.5. 
	startTime = db.FloatProperty()
	endTime = db.FloatProperty()
	availAccounts = db.ListProperty(db.Key)
	assignment = db.ReferenceProperty(Account, collection_name="shift_assignment_set")
	# "I have tenure. That means I can say whatever the hell I want to say." -ALK 2/8/12 
	sub = db.ReferenceProperty(Account, collection_name="shift_sub_set")
	up4grab =  db.BooleanProperty()

# Class Calendar: name, key, key of admin, status (open or closed boolean), 
# list of shifts, (closing date eventually - for now, manual)
# Short cal
class Calendar(db.Model):
	name = db.StringProperty()
	adminKey = db.ReferenceProperty(Admin)
	open = db.BooleanProperty()
	shifts = db.ListProperty(db.Key)

	
# These functions can be defined outsied of the MainPage class because they do 
# not require self.response.out.write funct
# Make the open test calendar
def createTestCalOpen():
	# Make the test calendar (open)
	# Add users to datastore
	admin1 = Admin(email='admin1@gmail.com', name='admin1', password='y35')
	admin1.put()
	user2 = User(email='user2@gmail.com', name='user2')
	user2.put()
	user3 = User(email='user3@gmail.com', name='user3')
	user3.put()
	
	sh1 = Shift()
	sh1.day = 1
	sh1.startTime = 12.5
	sh1.endTime = 15.0
	sh1.availAccounts = [admin1.key(), user2.key()]
	sh1.up4grab = False
	sh1.put()
	
	sh2 = Shift()
	sh2.day = 3
	sh2.startTime = 8.5
	sh2.endTime = 10.0
	sh2.availAccounts = [user2.key(), user3.key()]
	sh2.up4grab = False
	sh2.put()
	
	sh3 = Shift()
	sh3.day = 6
	sh3.startTime = 20.0
	sh3.endTime = 22.0
	sh3.availAccounts = [admin1.key(), user3.key()]
	sh3.up4grab = False
	sh3.put()
	
	cal = Calendar()
	cal.name = "Test Calendar open"
	cal.adminKey = admin1.key()
	cal.shifts = [sh1.key(), sh2.key(), sh3.key()]
	cal.open = True
	
	cal.put()

# Make the closed test calendar
def createTestCalClosed():
	users = [u for u in User.all()]
	user2 = users[0]
	user3 = users[1]
	admin1 = Admin.all().get()
	
	sh1 = Shift()
	sh1.day = 1
	sh1.startTime = 12.5
	sh1.endTime = 15.0
	sh1.availAccounts = [admin1.key(), user2.key()]
	sh1.assignment = admin1.key()
	sh1.put()
	
	sh2 = Shift()
	sh2.day = 3
	sh2.startTime = 8.5
	sh2.endTime = 10.0
	sh2.availAccounts = [user2.key(), user3.key()]
	sh2.assignment = user2.key()
	sh2.sub = user3.key()
	sh2.put()
	
	sh3 = Shift()
	sh3.day = 6
	sh3.startTime = 20.0
	sh3.endTime = 22.0
	sh3.availAccounts = [admin1.key(), user3.key()]
	sh3.assignment = admin1.key()
	sh3.up4grab = True
	sh3.put()
	
	cal = Calendar()
	cal.name = "Test Calendar closed"
	cal.adminKey = admin1.key()
	cal.shifts = [sh1.key(), sh2.key(), sh3.key()]
	cal.open = False
	cal.put()

# Run this to clear the database
def clearDb():
	for a in Account.all():
		a.delete()
	for sh in Shift.all():
		sh.delete()
	for cal in Calendar.all():
		cal.delete()
	
class MainPage(webapp2.RequestHandler):
	def get(self):
		# Print fuctions must be defined in MainPage class to use self.response.out.write function
		def printAc(ac):
			self.response.out.write("Account name: %s " % ac.name)
		
		def printSh(sh):
			self.response.out.write('Shift day: %s - startTime: %s <br/><b>Available accounts</b>' % (sh.day, sh.startTime))
			self.response.out.write('<ul>\n')
			for ack in sh.availAccounts:
				ac = Account.get(ack)
				self.response.out.write('<li>')
				printAc(ac)
				self.response.out.write('</li>\n')
			self.response.out.write('</ul>\n')
				
		def printCal(cal):
			self.response.out.write("""
			<h2>Calendar name: %s</h2>
			<h3>Shifts</h3>
			""" % cal.name)
			self.response.out.write('<ol>\n')
			for shk in cal.shifts:
				sh = Shift.get(shk)
				self.response.out.write('<li>')
				printSh(sh)
				self.response.out.write('</li>\n')
			self.response.out.write('</ol>\n')
					
		def printDb():
			self.response.out.write('<h1>Calendars</h1>')
			for cal in Calendar.all():
				printCal(cal)
			self.response.out.write('<h1>Shifts</h1>')
			for sh in Shift.all():
				printSh(sh)
			self.response.out.write('<h1>Accounts</h1>')
			for ac in Account.all():
				printAc(ac)
				self.response.out.write('<br/>')
				
	
		# Run this to clear the database
		clearDb()
		
		# Run these to create the test calendars
		# You only need to do this once unless you mess with the calendars and 
		# want to recreate them. They will be stored on your local datastore. 
		createTestCalOpen()		
		# createTestCalClosed()
		
		# Begin creating webpage
		self.response.out.write("<h1>Welcome to SlotMe-N!</h1>")
		
		# Print DB
		printDb()
		
		# Make list of all accounts
		#accounts = [account for account in Account.all()] 
		
		# Process all shifts
		# for shift in Shift.all():
		# shift.up4grab = False
		# shift.put()
		
		# "What happens in class, stays in class" -ALK 3/7/12
		
		# Show all users
		# getusr = Account.all().fetch(2)
		# for us in getusr:
		# self.response.out.write("email = %s; name = %s; key = %s <br/>" % (us.email, us.name, us.key()))
		# Assign them to shift
		# sh.availAccounts.append(us.key())
		# us.delete()
		
		# self.response.out.write("avaliable users: %s <br/>" % len(sh.availAccounts))
		# for k in sh.availAccounts:
		# av = db.get(k)
		# self.response.out.write("name = " + av.name + "<br/>")
		# self.response.out.write(k)
		# self.response.out.write('<br/>')
		
		# sh.put()
		
		# "That's not the aspect I have slides for" - ALK 4/23/12
		
		# cal = Calendar()
		# cal.name = "OrangeKey"
		# admin = 'spollard@gmail.com'
		# query = db.GqlQuery("SELECT * FROM Account WHERE email = :1", admin)
		# adminUsr = query.get()
		# cal.adminKey = adminUsr.key()
		
		# cal.shifts.append(db.Key('agxkZXZ-c2xvdG1lLW5yCwsSBVNoaWZ0GCEM'))
		
		# cal.put()
		
		# You can tell I stopped going to class as often because the spacing 
		# between quotes gets longer as the semester progresses, and we all know
		# that the quotes were uddered even when I wasn't there. 
		self.response.out.write("<h1>Done!</h1>")
	
		
app = webapp2.WSGIApplication([('/slotme-n-old', MainPage)],
                              debug=True)